import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class TCPFileClient extends FileClient {

	private HashMap<Integer, FilePart> partList;
	
	private Socket clientSocket;
	public TCPFileClient(String hostName, int port) throws UnknownHostException, IOException {
		super(hostName, port);
		clientSocket= new Socket(getHostName(), getPort());// Tao clinent socket de ket noi toi server
		
		partList = new HashMap<Integer, FilePart>();
	}

	@Override
	public void CallServer() throws IOException {
		String message;// Cau duoc gui toi server
        String ketQua;//Cau duoc server xu ly va tra lai la in hoa
        
        BufferedReader inFormUser= new BufferedReader(new InputStreamReader(System.in));// Tao input stream
        DataOutputStream sendToServer= new DataOutputStream(clientSocket.getOutputStream());// Tao output stream ket noi toi socket
        BufferedReader inFromServer = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
        
        String fileName = "";
        String filePath = "";
        File f = null;
        FileOutputStream outf = null;
        String downloadFolderPath = System.getProperty("user.dir") + "\\Download\\";
        
        boolean isGetFile = false;
        boolean isDownloadFile = false;
        
        ketQua = inFromServer.readLine();// get Wellcome message
        System.out.println(ketQua);
        while(true)
        {
        	if(!isGetFile || !isDownloadFile){
        		message = inFormUser.readLine();// Nhap vao 1 cau
                sendToServer.writeBytes(message+'\n');// gui toi server
                if(message.length() >= 4 && message.substring(0, 4).equalsIgnoreCase("get ")){
                	//ready for revcive
                	partList.clear();
                	
                	fileName = message.substring(4).trim();
                	filePath = downloadFolderPath + fileName;
                	isGetFile = true;
                }
                if (message.equalsIgnoreCase("bye"))// Gap chuoi quit
                    break;
        	}
        	
        	
        	ketQua = inFromServer.readLine();// Nhan lai tu server
        	if(isGetFile && !isDownloadFile){
        		if(ketQua.equalsIgnoreCase("101")){
            		System.out.println("FROM SERVER: File not found !");
            		isGetFile = false;
            	}
            	if(ketQua.equalsIgnoreCase("100")){
            		System.out.println("FROM SERVER: Rev file...");
            		f = new File(filePath);
                	outf = new FileOutputStream(f);
            		
            		isDownloadFile = true;
            		sendToServer.writeBytes("get" + '\n');// gui toi server
            	}
            	continue;
        	}
        	if(isGetFile && isDownloadFile){
        		if(ketQua.equalsIgnoreCase("199")){
        			System.out.println("File: " + fileName + " download done !");
        			int i = 0;
        			while(!FileUtility.checkFileDone(partList) || i <= partList.keySet().size()*2){
        				FileUtility.saveFileUpdate(partList, outf);
        				i++;
        			}
        			outf.close();
        			
        			isGetFile = isDownloadFile = false;
        		}else{
        			//System.out.println("FROM SERVER: "+ketQua);
        			//Xu ly ket qua
        			Pattern r = Pattern.compile("<file>(.*)</file><part>(\\d+)</part><length>(\\d+)</length><data>(.*)</data>");
        			Matcher m = r.matcher(ketQua);
        			
        			if (!m.matches( )) continue;
        			
        			String fname = m.group(1);
        			int part = Integer.parseInt(m.group(2));
        			int length = Integer.parseInt(m.group(3));
        			String dataStr = m.group(4);
        			
            		System.out.println("File: " + fname + "; Part: " + part + "; PacketLength: " + length);
            		//Luu vao partList
            		partList.put(new Integer(part), new FilePart(FileUtility.Base64ToBytes(dataStr), 0));
            		
            		//save to file
            		FileUtility.saveFileUpdate(partList, outf);
            		
            		sendToServer.writeBytes("get" + '\n');// yeu cau server gui part tiep theo
        		}
        		continue;
        	}
        	
        	System.out.println("FROM SERVER: "+ketQua);
        }
        clientSocket.close();//Dong ket noi

	}
	


	@Override
	public void showInfo() {
		System.out.println("TCP File Client");
		System.out.println("Connect to: " + getHostName() + " ; Port: " + getPort());
		
	}

}
